Skip to content

Conversation

mnocon
Copy link
Contributor

@mnocon mnocon commented May 12, 2025

Question Answer
JIRA Ticket https://issues.ibexa.co/browse/IBX-9935
Versions master, 4.6
Edition all

Doc for ibexa/admin-ui#1537

Preview: https://ez-systems-developer-documentation--2735.com.readthedocs.build/en/2735/administration/back_office/subitems_list/

Some changes compared to the examples from PR:

  • added Ibexa's SCSS variable import for consistency with our UI
  • changed ibexa prefixes to app

The example has been updated to work with v5 in:
ba9e392

this commit will be reverted manually when cherry-picking to 4.6

Checklist

  • Text renders correctly
  • Text has been checked with vale
  • Description metadata is up to date
  • Redirects cover removed/moved pages
  • Code samples are working
  • PHP code samples have been fixed with PHP CS fixer
  • Added link to this PR in relevant JIRA ticket or code PR

@mnocon mnocon marked this pull request as ready for review May 12, 2025 09:17
Copy link

github-actions bot commented May 12, 2025

@mnocon mnocon requested a review from dew326 May 12, 2025 09:39
@mnocon mnocon changed the title Subitems view [Subitems] Add extensibility point to add new views May 12, 2025
!!! caution
## Add custom sub-items list view

You can extend the Sub-items List module to add your own views to it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or override the existing view?
If you pass the existing viewName as a first parameter in registerView(), you will override the existing view with your own. https://github.com/ibexa/admin-ui/blob/main/src/bundle/ui-dev/src/modules/sub-items/services/view.registry.js#L26
I think it is worth mentioning because this was the original customer problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, added in 34c5442

@mnocon mnocon requested a review from dew326 May 12, 2025 11:15
Copy link
Contributor

@adriendupuis adriendupuis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed the steps with success on 4.6.x-dev (with reverting 30348fb)

I would remind to run composer run post-install-cmd for Encore to be re-compiled.

@mnocon mnocon added Wait with merge PRs that shouldn't be merged instantly Ready for MERGE and removed Needs DOC review labels May 15, 2025
Copy link

code_samples/ change report

Before (on target branch)After (in current PR)

code_samples/back_office/subitems/render_subitems.js


code_samples/back_office/subitems/render_subitems.js

docs/administration/back_office/subitems_list.md@87:``` js
docs/administration/back_office/subitems_list.md@88:[[= include_file('code_samples/back_office/subitems/render_subitems.js') =]]
docs/administration/back_office/subitems_list.md@89:```

001⫶const containerNode = document.querySelector('#sub-items-container');
002⫶
003⫶ReactDOM.render(
004⫶ React.createElement(ibexa.modules.SubItems, {
005⫶ parentLocationId: { Number },
006⫶ restInfo: {
007⫶ token: { String },
008⫶ siteaccess: { String },
009⫶ },
010⫶ }),
011⫶ containerNode,
012⫶);

docs/administration/back_office/subitems_list.md@93:``` jsx
docs/administration/back_office/subitems_list.md@94:[[= include_file('code_samples/back_office/subitems/render_subitems.jsx') =]]
docs/administration/back_office/subitems_list.md@95:```

001⫶const attrs = {
002⫶ parentLocationId: {Number},
003⫶ restInfo: {
004⫶ token: {String},
005⫶ siteaccess: {String}
006⫶ }
007⫶};
008⫶
009⫶<SubItemsModule {...attrs}/>


code_samples/back_office/subitems/render_subitems.jsx


code_samples/back_office/subitems/render_subitems.jsx

docs/administration/back_office/subitems_list.md@93:``` jsx
docs/administration/back_office/subitems_list.md@94:[[= include_file('code_samples/back_office/subitems/render_subitems.jsx') =]]
docs/administration/back_office/subitems_list.md@95:```

001⫶const attrs = {
002⫶ parentLocationId: {Number},
003⫶ restInfo: {
004⫶ token: {String},
005⫶ siteaccess: {String}
006⫶ }
007⫶};
008⫶
009⫶<SubItemsModule {...attrs}/>


code_samples/back_office/subitems/timeline_view/registerTimelineView.js


code_samples/back_office/subitems/timeline_view/registerTimelineView.js

docs/administration/back_office/subitems_list.md@48:``` js
docs/administration/back_office/subitems_list.md@49:[[= include_file('code_samples/back_office/subitems/timeline_view/registerTimelineView.js') =]]
docs/administration/back_office/subitems_list.md@50:```

001⫶import TimelineViewComponent from './timeline.view.component.js';
002⫶import { registerView } from '@ibexa-admin-ui-modules/sub-items/services/view.registry';
003⫶
004⫶// Use the existing constants to replace a view
005⫶import { VIEW_MODE_GRID, VIEW_MODE_TABLE } from '@ibexa-admin-ui-modules/sub-items/constants';
006⫶
007⫶registerView('timeline', {
008⫶ component: TimelineViewComponent,
009⫶ iconName: 'timeline',
010⫶ label: 'Timeline view',
011⫶});


code_samples/back_office/subitems/timeline_view/timeline.view.component.js


code_samples/back_office/subitems/timeline_view/timeline.view.component.js

docs/administration/back_office/subitems_list.md@22:``` js
docs/administration/back_office/subitems_list.md@23:[[= include_file('code_samples/back_office/subitems/timeline_view/timeline.view.component.js') =]]
docs/administration/back_office/subitems_list.md@24:```

001⫶import React from 'react';
002⫶import PropTypes from 'prop-types';
003⫶import TimelineViewItemComponent from './timeline.view.item.component';
004⫶
005⫶const TimelineViewComponent = ({ items, generateLink }) => {
006⫶ const groupByDate = (items) => {
007⫶ return items.reduce((groups, item) => {
008⫶ const date = new Date(item.content._info.modificationDate.timestamp * 1000);
009⫶ const dateKey = date.toISOString().split('T')[0];
010⫶
011⫶ if (!groups[dateKey]) {
012⫶ groups[dateKey] = [];
013⫶ }
014⫶
015⫶ groups[dateKey].push(item);
016⫶ return groups;
017⫶ }, {});
018⫶ };
019⫶
020⫶ const groupedItems = groupByDate(items);
021⫶
022⫶ return (
023⫶ <div className="app-timeline-view">
024⫶ {Object.entries(groupedItems).map(([date, dateItems]) => (
025⫶ <div key={date} className="app-timeline-view__group">
026⫶ <div className="app-timeline-view__date">
027⫶ <div className="app-timeline-view__date-marker" />
028⫶ <h3>{new Date(date).toLocaleDateString()}</h3>
029⫶ </div>
030⫶ <div className="app-timeline-view__items">
031⫶ {dateItems.map((item) => (
032⫶ <TimelineViewItemComponent key={item.id} item={item} generateLink={generateLink} />
033⫶ ))}
034⫶ </div>
035⫶ </div>
036⫶ ))}
037⫶ </div>
038⫶ );
039⫶};
040⫶
041⫶TimelineViewComponent.propTypes = {
042⫶ items: PropTypes.array.isRequired,
043⫶ generateLink: PropTypes.func.isRequired,
044⫶};
045⫶
046⫶export default TimelineViewComponent;


code_samples/back_office/subitems/timeline_view/timeline.view.item.component.js


code_samples/back_office/subitems/timeline_view/timeline.view.item.component.js

docs/administration/back_office/subitems_list.md@28:``` js
docs/administration/back_office/subitems_list.md@29:[[= include_file('code_samples/back_office/subitems/timeline_view/timeline.view.item.component.js') =]]
docs/administration/back_office/subitems_list.md@30:```

001⫶import React from 'react';
002⫶import PropTypes from 'prop-types';
003⫶import Icon from '@ibexa-admin-ui-modules/common/icon/icon';
004⫶
005⫶const { ibexa } = window;
006⫶
007⫶const TimelineViewItemComponent = ({ item, generateLink }) => {
008⫶ const { content } = item;
009⫶ const contentTypeIdentifier = content._info.contentType.identifier;
010⫶ const contentTypeIconUrl = ibexa.helpers.contentType.getContentTypeIconUrl(contentTypeIdentifier);
011⫶ const time = new Date(content._info.modificationDate.timestamp * 1000).toLocaleTimeString();
012⫶
013⫶ return (
014⫶ <a className="app-timeline-view-item" href={generateLink(item.id, content._info.id)}>
015⫶ <div className="app-timeline-view-item__time">{time}</div>
016⫶ <div className="app-timeline-view-item__content">
017⫶ <div className="app-timeline-view-item__info">
018⫶ <div className="app-timeline-view-item__name">{content._name}</div>
019⫶ <div className="app-timeline-view-item__type">
020⫶ <Icon customPath={contentTypeIconUrl} extraClasses="ibexa-icon--small" />
021⫶ <span className="app-timeline-view-item__type-name">{content._info.contentType.name}</span>
022⫶ </div>
023⫶ </div>
024⫶ </div>
025⫶ </a>
026⫶ );
027⫶};
028⫶
029⫶TimelineViewItemComponent.propTypes = {
030⫶ item: PropTypes.object.isRequired,
031⫶ generateLink: PropTypes.func.isRequired,
032⫶};
033⫶
034⫶export default TimelineViewItemComponent;


code_samples/back_office/subitems/timeline_view/timeline.view.scss


code_samples/back_office/subitems/timeline_view/timeline.view.scss

docs/administration/back_office/subitems_list.md@34:``` scss
docs/administration/back_office/subitems_list.md@35:[[= include_file('code_samples/back_office/subitems/timeline_view/timeline.view.scss') =]]
docs/administration/back_office/subitems_list.md@36:```

001⫶@use '@ibexa-admin-ui/src/bundle/Resources/public/scss/custom.scss' as *;
002⫶
003⫶.app-timeline-view {
004⫶ padding: calculateRem(16px);
005⫶
006⫶ &__group {
007⫶ position: relative;
008⫶ margin-bottom: calculateRem(32px);
009⫶ }
010⫶
011⫶ &__date {
012⫶ display: flex;
013⫶ align-items: center;
014⫶ margin-bottom: calculateRem(16px);
015⫶
016⫶ h3 {
017⫶ margin: 0;
018⫶ font-size: $ibexa-text-font-size-large;
019⫶ color: $ibexa-color-dark;
020⫶ }
021⫶ }
022⫶
023⫶ &__date-marker {
024⫶ width: calculateRem(12px);
025⫶ height: calculateRem(12px);
026⫶ border-radius: 50%;
027⫶ background: $ibexa-color-primary;
028⫶ margin-right: calculateRem(16px);
029⫶ }
030⫶
031⫶ &__items {
032⫶ margin-left: calculateRem(6px);
033⫶ padding-left: calculateRem(32px);
034⫶ border-left: calculateRem(2px) solid $ibexa-color-light;
035⫶ }
036⫶}
037⫶
038⫶.app-timeline-view-item {
039⫶ display: flex;
040⫶ align-items: flex-start;
041⫶ padding: calculateRem(16px);
042⫶ margin-bottom: calculateRem(8px);
043⫶ text-decoration: none;
044⫶ color: inherit;
045⫶ background: $ibexa-color-light-300;
046⫶ border-radius: $ibexa-border-radius;
047⫶ transition: background-color 0.2s $ibexa-admin-transition;
048⫶
049⫶ &:hover {
050⫶ background: $ibexa-color-light-400;
051⫶ }
052⫶
053⫶ &__time {
054⫶ color: $ibexa-color-dark-400;
055⫶ margin-right: calculateRem(16px);
056⫶ min-width: calculateRem(80px);
057⫶ }
058⫶
059⫶ &__content {
060⫶ display: flex;
061⫶ align-items: center;
062⫶ }
063⫶
064⫶ &__icon {
065⫶ margin-right: calculateRem(16px);
066⫶ }
067⫶
068⫶ &__name {
069⫶ font-weight: $ibexa-font-weight-bold;
070⫶ margin-bottom: calculateRem(4px);
071⫶ }
072⫶
073⫶ &__type {
074⫶ font-size: $ibexa-text-font-size-small;
075⫶ color: $ibexa-color-dark-400;
076⫶ display: flex;
077⫶ align-items: center;
078⫶ gap: calculateRem(8px);
079⫶ }
080⫶
081⫶ &__type-name {
082⫶ line-height: calculateRem(16px);
083⫶ }
084⫶}

Download colorized diff

@mnocon mnocon changed the base branch from master to 5.0 May 19, 2025 07:25
@mnocon mnocon merged commit 48f1610 into 5.0 May 28, 2025
6 of 7 checks passed
@mnocon mnocon deleted the subitems-view branch May 28, 2025 06:36
mnocon added a commit that referenced this pull request May 28, 2025
* Before prefix change

* Prefixes

* Screenshot

* Adjusted example to v5

* Vale suggestion

* Added mention about replacing a view

* Improvements

* Added mention of composer run post-install-cmd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for MERGE Wait with merge PRs that shouldn't be merged instantly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants